package cn.jon.androidbanneranimation

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.RecyclerView

class InfiniteAutoScrollRecyclerView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {

    // 配置参数
    var autoScrollInterval = 2000L // 自动滚动间隔
    var pauseAfterUserInteraction = 2000L // 用户操作后暂停时间
    var itemScaleFactor = 1.5f // Item放大系数
    var animationDuration = 300L // 动画持续时间
    var enableInfiniteScroll = true // 是否启用循环滚动
    var autoScrollStartDelay = 1000L // 自动滚动开始延迟时间

    // 内部状态
    private val autoScrollHandler = Handler(Looper.getMainLooper())
    private val resumeHandler = Handler(Looper.getMainLooper())
    private var autoScrollRunnable: Runnable? = null
    private var resumeRunnable: Runnable? = null
    private var isUserInteracting = false
    private var currentScaledView: View? = null
    private var lastTouchTime = 0L
    private var currentPosition = 0

    // 循环滚动相关
    private var originalAdapter: Adapter<*>? = null
    private var infiniteAdapter: InfiniteScrollAdapter? = null
    private val multiplier = 1000 // 循环滚动的乘数

    // 用于存储原始宽度的Map
    private val originalWidthMap = mutableMapOf<View, Int>()

    init {
        Log.d("AutoScrollBanner", "AutoScrollBannerRecyclerView initialized")
        setupLayoutManager()
        setupScrollListener()
        setupItemAnimator()
    }

    private fun setupLayoutManager() {
        val layoutManager = object : LinearLayoutManager(context, HORIZONTAL, false) {
            override fun smoothScrollToPosition(recyclerView: RecyclerView, state: State, position: Int) {
                val smoothScroller = object : LinearSmoothScroller(context) {
                    override fun getHorizontalSnapPreference(): Int = SNAP_TO_START
                    override fun calculateTimeForScrolling(dx: Int): Int = 300 // 滚动动画时间
                }
                smoothScroller.targetPosition = position
                startSmoothScroll(smoothScroller)
            }
        }
        this.layoutManager = layoutManager
    }

    private fun setupItemAnimator() {
        // 关闭默认动画，使用自定义动画
        itemAnimator = null
    }

    override fun setAdapter(adapter: Adapter<ViewHolder>?) {
        Log.d("AutoScrollBanner", "setAdapter called, enableInfiniteScroll: $enableInfiniteScroll")
        originalAdapter = adapter

        if (enableInfiniteScroll && adapter != null && adapter.itemCount > 0) {
            Log.d("AutoScrollBanner", "Setting up infinite scroll adapter")
            infiniteAdapter = InfiniteScrollAdapter(adapter)
            super.setAdapter(infiniteAdapter)

            // 滚动到中间位置
            post {
                val centerPosition = infiniteAdapter!!.itemCount / 2
                val adjustedCenter = centerPosition - (centerPosition % adapter.itemCount)
                currentPosition = adjustedCenter
                scrollToPosition(currentPosition)

                // 启动自动滚动
                if (autoScrollStartDelay > 0) {
                    postDelayed({ startAutoScroll() }, autoScrollStartDelay)
                } else {
                    startAutoScroll()
                }
            }
        } else {
            Log.d("AutoScrollBanner", "Setting up normal adapter")
            infiniteAdapter = null
            super.setAdapter(adapter)
            currentPosition = 0

            // 启动自动滚动
            if (autoScrollStartDelay > 0) {
                postDelayed({ startAutoScroll() }, autoScrollStartDelay)
            } else {
                startAutoScroll()
            }
        }
    }

    private fun setupScrollListener() {
        addOnScrollListener(object : OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                Log.d("AutoScrollBanner", "Scroll state changed: $newState")

                when (newState) {
                    SCROLL_STATE_DRAGGING -> {
                        onUserInteractionStart()
                    }
                    SCROLL_STATE_SETTLING -> {
                        // 滚动过程中
                    }
                    SCROLL_STATE_IDLE -> {
                        updateCurrentPosition()

                        if (isUserInteracting) {
                            // 用户操作后对齐到最近的Item
                            snapToNearestItem()
                        } else {
                            // 自动滚动完成，执行动画
                            executeItemAnimations()
                        }
                    }
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                // 检查循环滚动边界
                if (enableInfiniteScroll) {
                    checkInfiniteScrollBoundary()
                }
                // 检查并重置离开屏幕的Item宽度
                resetOffScreenItemWidths()
            }
        })
    }

    private fun resetOffScreenItemWidths() {
        val layoutManager = layoutManager as? LinearLayoutManager ?: return
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
        val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()

        // 遍历所有缓存的宽度记录，检查是否需要重置
        val iterator = originalWidthMap.iterator()
        while (iterator.hasNext()) {
            val entry = iterator.next()
            val view = entry.key
            val originalWidth = entry.value

            // 检查这个view是否还在屏幕上
            val viewPosition = getChildAdapterPosition(view)
            if (viewPosition < firstVisiblePosition || viewPosition > lastVisiblePosition || viewPosition == RecyclerView.NO_POSITION) {
                // View已经离开屏幕，重置其宽度
                view.layoutParams?.let { params ->
                    if (params.width != originalWidth) {
                        params.width = originalWidth
                        view.layoutParams = params
                        Log.d("AutoScrollBanner", "Reset width for off-screen view at position $viewPosition")
                    }
                }
                iterator.remove()
            }
        }
    }

    private fun updateCurrentPosition() {
        val layoutManager = layoutManager as? LinearLayoutManager ?: return
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
        if (firstVisiblePosition != RecyclerView.NO_POSITION) {
            currentPosition = firstVisiblePosition
            Log.d("AutoScrollBanner", "Current position updated to: $currentPosition")
        }
    }

    private fun checkInfiniteScrollBoundary() {
        if (!enableInfiniteScroll || infiniteAdapter == null) return

        val layoutManager = layoutManager as? LinearLayoutManager ?: return
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
        val totalItems = infiniteAdapter!!.itemCount
        val originalItemCount = infiniteAdapter!!.getOriginalItemCount()

        // 如果接近边界，跳转到安全位置
        when {
            firstVisiblePosition < originalItemCount -> {
                val safePosition = firstVisiblePosition + originalItemCount * (multiplier / 4)
                scrollToPosition(safePosition)
                currentPosition = safePosition
            }
            firstVisiblePosition > totalItems - originalItemCount -> {
                val safePosition = firstVisiblePosition - originalItemCount * (multiplier / 4)
                scrollToPosition(safePosition)
                currentPosition = safePosition
            }
        }
    }

    override fun onTouchEvent(e: MotionEvent?): Boolean {
        when (e?.action) {
            MotionEvent.ACTION_DOWN -> {
                lastTouchTime = System.currentTimeMillis()
                onUserInteractionStart()
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                scheduleResumeAutoScroll()
            }
        }
        return super.onTouchEvent(e)
    }

    private fun onUserInteractionStart() {
        if (!isUserInteracting) {
            Log.d("AutoScrollBanner", "User interaction started")
            isUserInteracting = true
            stopAutoScroll()
        }
    }

    private fun scheduleResumeAutoScroll() {
        resumeRunnable?.let { resumeHandler.removeCallbacks(it) }
        resumeRunnable = Runnable {
            val currentTime = System.currentTimeMillis()
            if (currentTime - lastTouchTime >= pauseAfterUserInteraction) {
                Log.d("AutoScrollBanner", "Resuming auto scroll")
                isUserInteracting = false
                startAutoScroll()
            }
        }
        resumeHandler.postDelayed(resumeRunnable!!, pauseAfterUserInteraction)
    }

    private fun startAutoScroll() {
        stopAutoScroll()
        Log.d("AutoScrollBanner", "Starting auto scroll")

        autoScrollRunnable = Runnable {
            if (!isUserInteracting) {
                scrollToNextItem()
                autoScrollHandler.postDelayed(autoScrollRunnable!!, autoScrollInterval)
            }
        }
        autoScrollHandler.postDelayed(autoScrollRunnable!!, autoScrollInterval)
    }

    private fun stopAutoScroll() {
        autoScrollRunnable?.let {
            autoScrollHandler.removeCallbacks(it)
            Log.d("AutoScrollBanner", "Auto scroll stopped")
        }
        resumeRunnable?.let { resumeHandler.removeCallbacks(it) }
    }

    private fun scrollToNextItem() {
        val adapter = adapter ?: return
        val itemCount = if (enableInfiniteScroll && infiniteAdapter != null) {
            infiniteAdapter!!.itemCount
        } else {
            adapter.itemCount
        }

        if (itemCount == 0) return

        val nextPosition = if (enableInfiniteScroll) {
            currentPosition + 1
        } else {
            // 普通模式：循环到第一个
            if (currentPosition + 1 >= itemCount) 0 else currentPosition + 1
        }

        Log.d("AutoScrollBanner", "Scrolling from $currentPosition to $nextPosition")
        currentPosition = nextPosition
        smoothScrollToPosition(nextPosition)
    }

    private fun snapToNearestItem() {
        val layoutManager = layoutManager as? LinearLayoutManager ?: return
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()

        if (firstVisiblePosition != RecyclerView.NO_POSITION) {
            val firstVisibleView = layoutManager.findViewByPosition(firstVisiblePosition)
            firstVisibleView?.let { view ->
                val itemLeft = view.left
                val snapThreshold = view.width / 3

                val targetPosition = if (itemLeft < -snapThreshold &&
                    firstVisiblePosition + 1 < adapter?.itemCount ?: 0) {
                    firstVisiblePosition + 1
                } else {
                    firstVisiblePosition
                }

                if (targetPosition != firstVisiblePosition) {
                    currentPosition = targetPosition
                    smoothScrollToPosition(targetPosition)
                } else {
                    // 已经对齐，延迟执行动画
                    postDelayed({ executeItemAnimations() }, 100)
                }
            }
        }
    }

    private fun executeItemAnimations() {
        val layoutManager = layoutManager as? LinearLayoutManager ?: return
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()

        if (firstVisiblePosition == RecyclerView.NO_POSITION) return

        val targetView = layoutManager.findViewByPosition(firstVisiblePosition)
        targetView?.let { view ->
            Log.d("AutoScrollBanner", "Executing animations for position: $firstVisiblePosition")

            // 先执行Item宽度变化动画
            executeItemWidthAnimation(view) {
                // 宽度变化完成后执行内部控件动画
                executeInnerViewAnimations(view)
            }
        }
    }

    private fun executeItemWidthAnimation(view: View, onComplete: () -> Unit) {
        // 重置之前的Item
        currentScaledView?.let { resetItemWidth(it) }
        currentScaledView = view

        // 保存原始宽度
        val originalWidth = view.layoutParams.width
        if (!originalWidthMap.containsKey(view)) {
            originalWidthMap[view] = originalWidth
        }

        // 计算目标宽度
        val targetWidth = (originalWidth * itemScaleFactor).toInt()

        Log.d("AutoScrollBanner", "Starting width animation: $originalWidth -> $targetWidth")

        // 创建宽度变化动画
        val widthAnimator = ValueAnimator.ofInt(originalWidth, targetWidth)
        widthAnimator.addUpdateListener { animator ->
            val animatedWidth = animator.animatedValue as Int
            view.layoutParams?.let { params ->
                params.width = animatedWidth
                view.layoutParams = params
            }
        }

        val animatorSet = AnimatorSet()
        animatorSet.play(widthAnimator)

        animatorSet.duration = animationDuration
        animatorSet.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                Log.d("AutoScrollBanner", "Item width animation completed")

                // 宽度变化完成后，重新对齐
                postDelayed({
                    adjustItemPositionAfterResize()
                    onComplete()
                }, 50)
            }
        })
        animatorSet.start()
    }

    private fun adjustItemPositionAfterResize() {
        // Item宽度变化后需要重新对齐位置
        val layoutManager = layoutManager as? LinearLayoutManager ?: return
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()

        if (firstVisiblePosition != RecyclerView.NO_POSITION) {
            // 使用scrollToPosition确保Item完全左对齐
            post {
                scrollToPosition(firstVisiblePosition)
            }
        }
    }

    private fun resetItemWidth(view: View) {
        // 恢复原始宽度
        val originalWidth = originalWidthMap[view]
        if (originalWidth != null) {
            view.layoutParams?.let { params ->
                params.width = originalWidth
                view.layoutParams = params
            }
        }

        // 同时重置内部控件状态
        val imageView = findImageViewInHierarchy(view)
        val descriptionTextView = findDescriptionTextViewInHierarchy(view)
        val titleTextView = view.findViewById<TextView>(R.id.titleTextView)

        imageView?.let { iv ->
            iv.visibility = View.INVISIBLE
            iv.alpha = 0f
            iv.translationX = 0f
        }

        titleTextView?.let { tv ->
            tv.alpha = 1f
            tv.scaleX = 1f // 重置titleTextView的缩放
            tv.scaleY = 1f
        }

        descriptionTextView?.let { tv ->
            tv.visibility = View.INVISIBLE // descriptionTextView回到不可见状态
            tv.alpha = 0f
        }
    }

    private fun executeInnerViewAnimations(itemView: View) {
        val imageView = findImageViewInHierarchy(itemView)
        val descriptionTextView = findDescriptionTextViewInHierarchy(itemView)

        Log.d("AutoScrollBanner", "Found imageView: ${imageView != null}, descriptionTextView: ${descriptionTextView != null}")

        // 先执行ImageView动画，完成后执行descriptionTextView动画
        imageView?.let { iv ->
            executeImageViewAnimation(iv) {
                // ImageView动画完成后，执行descriptionTextView动画
                descriptionTextView?.let { tv ->
                    executeDescriptionTextAnimation(tv)
                }
            }
        } ?: run {
            // 如果没有ImageView，直接执行descriptionTextView动画
            descriptionTextView?.let { tv ->
                executeDescriptionTextAnimation(tv)
            }
        }
    }

    private fun executeImageViewAnimation(imageView: ImageView, onComplete: () -> Unit) {
        Log.d("AutoScrollBanner", "Starting ImageView animation")

        // 设置初始状态
        imageView.visibility = View.VISIBLE
        imageView.alpha = 0f
        imageView.translationX = 0f

        // 创建透明度和位移动画
        val alphaAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f)
        val translationAnimator = ObjectAnimator.ofFloat(imageView, "translationX", 0f, imageView.width.toFloat())

        val animatorSet = AnimatorSet()
        animatorSet.playTogether(alphaAnimator, translationAnimator)
        animatorSet.duration = animationDuration
        animatorSet.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                Log.d("AutoScrollBanner", "ImageView animation completed")
                onComplete()
            }
        })
        animatorSet.start()
    }

    private fun executeDescriptionTextAnimation(textView: TextView) {
        Log.d("AutoScrollBanner", "Starting descriptionTextView animation")

        // 设置初始状态
        textView.visibility = View.VISIBLE
        textView.alpha = 0f

        // 创建透明度动画
        val alphaAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f)
        alphaAnimator.duration = animationDuration
        alphaAnimator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                Log.d("AutoScrollBanner", "DescriptionTextView animation completed")
            }
        })
        alphaAnimator.start()
    }

    private fun findImageViewInHierarchy(parent: View): ImageView? {
        if (parent is ImageView) return parent
        if (parent is ViewGroup) {
            for (i in 0 until parent.childCount) {
                val child = parent.getChildAt(i)
                val result = findImageViewInHierarchy(child)
                if (result != null) return result
            }
        }
        return null
    }

    private fun findTextViewInHierarchy(parent: View): TextView? {
        if (parent is TextView) return parent
        if (parent is ViewGroup) {
            for (i in 0 until parent.childCount) {
                val child = parent.getChildAt(i)
                val result = findTextViewInHierarchy(child)
                if (result != null) return result
            }
        }
        return null
    }

    private fun findDescriptionTextViewInHierarchy(parent: View): TextView? {
        // 通过ID查找descriptionTextView
        val descriptionTextView = parent.findViewById<TextView>(R.id.descriptionTextView)
        return descriptionTextView
    }

    fun startAutoScrollImmediately() {
        post { startAutoScroll() }
    }

    fun pauseAutoScroll() {
        stopAutoScroll()
    }

    fun resumeAutoScroll() {
        if (!isUserInteracting) {
            startAutoScroll()
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        stopAutoScroll()
        originalWidthMap.clear() // 清理宽度缓存
    }

    // 循环滚动适配器
    private class InfiniteScrollAdapter(private val originalAdapter: Adapter<ViewHolder>) :
        Adapter<ViewHolder>() {

        private val multiplier = 1000

        fun getOriginalItemCount(): Int = originalAdapter.itemCount

        override fun getItemCount(): Int {
            return if (originalAdapter.itemCount > 0) {
                originalAdapter.itemCount * multiplier
            } else 0
        }

        override fun getItemViewType(position: Int): Int {
            return if (originalAdapter.itemCount > 0) {
                originalAdapter.getItemViewType(position % originalAdapter.itemCount)
            } else 0
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return originalAdapter.onCreateViewHolder(parent, viewType)
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            if (originalAdapter.itemCount > 0) {
                val actualPosition = position % originalAdapter.itemCount
                originalAdapter.onBindViewHolder(holder, actualPosition)
            }
        }

        override fun onViewRecycled(holder: ViewHolder) {
            originalAdapter.onViewRecycled(holder)
        }

        override fun onViewAttachedToWindow(holder: ViewHolder) {
            originalAdapter.onViewAttachedToWindow(holder)
        }

        override fun onViewDetachedFromWindow(holder: ViewHolder) {
            originalAdapter.onViewDetachedFromWindow(holder)
        }
    }
}